package com.jumper.study.admin.controller;

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.RequestParam;

import com.jumper.study.admin.dto.resp.UploadResp;
import com.jumper.study.common.api.CommonResult;
import com.jumper.study.common.util.StrUtil;

@RestController
@RequestMapping("/api")
public class UploadController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UploadController.class);

    @Value("${study-setting.upload.dir}")
    private String uploadDir;

    @Value("${study-setting.upload.mimes}")
    private List<String> allowMimes;

    @PostMapping("/upload")
    public CommonResult<UploadResp> upload(@RequestParam("file") MultipartFile f) throws IOException {
        if (f == null || StrUtil.isEmpty(f.getOriginalFilename())) {
            return CommonResult.failed("未选择文件");
        }
        if (!verifyFileType(f.getContentType())) {
            return CommonResult.failed("非法的文件类型");
        }
        LOGGER.debug("setting upload path:{}", uploadDir);

        String newName = saveFile(f, uploadDir);

        return CommonResult.success(new UploadResp(newName, f.getOriginalFilename()));
    }

    @PostMapping("/uploads")
    public CommonResult<List<UploadResp>> uploads(@RequestParam("files[]") MultipartFile[] files) throws IOException {
        if (files == null) {
            return CommonResult.failed("未选择上传文件");
        }

        List<UploadResp> resps = new ArrayList<>();
        for(MultipartFile file : files) {
            if (file == null || StrUtil.isEmpty(file.getOriginalFilename())) {
                continue;
            }
            if (!verifyFileType(file.getContentType())) {
                continue;
            }

            resps.add(new UploadResp(saveFile(file, uploadDir), file.getOriginalFilename()));
        }

        return CommonResult.success(resps);
    }

    //检测文件mime类型
    private boolean verifyFileType(String mimeType) {
        LOGGER.debug("upload mime:{}", mimeType);
        return allowMimes.contains(mimeType);
    }

    private String saveFile(MultipartFile f, String path) throws IOException {
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        String originName = f.getOriginalFilename();
        String newPath = String.format("%s/%s/%s", path, datePath, originName);
        String newName = originName;
        if (originName != null) {
            LOGGER.debug("path:{}, datePath:{}, newName:{}", path, datePath, newName);
            String ext = originName.substring(originName.lastIndexOf("."));
            ThreadLocalRandom random = ThreadLocalRandom.current();
            newName = String.format("%s/%s%d%s", datePath, LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli(), random.nextInt(1000), ext);
            newPath = String.format("%s/%s", path, newName);
        }
        File dir = new File(String.format("%s/%s", path, datePath));
        if (!dir.exists()) {
            dir.mkdir();
        }

        LOGGER.debug("upload path:{}, {}, {}", dir.getPath(), newPath, newName);
        File file = new File(newPath);
        f.transferTo(file);
        return newName;
    }
}
